﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Reflection;

namespace ICSharpCode.WinFormsUI.Controls
{
    public partial class NButton : Control
    {
        private int _radius;
        [Category("杂项")]
        public int Radius
        {
            get { return _radius; }
            set
            {
                _radius = value;
                this.Invalidate();
            }
        }

        private bool _foused = false;
        [Category("杂项")]
        public bool Foused
        {
            get { return _foused; }
            set
            {
                _foused = value;
                this.Invalidate();
            }
        }

        private string _text;
        [Category("杂项")]
        public override string Text
        {
            get { return _text; }
            set
            {
                _text = value;
                this.Invalidate();
            }
        }

        private Bitmap _unableicon;
        [Category("杂项")]
        public Bitmap UnableIcon
        {
            get { return _unableicon; }
            set { _unableicon = value; }
        }

        private Bitmap _icon;
        [Category("杂项")]
        public Bitmap Icon
        {
            get { return _icon; }
            set
            {
                _icon = value;
                if (_icon != null)
                {
                    _unableicon = Discolor((Bitmap)_icon);
                }
                this.Invalidate();
            }
        }

        private Color _foreColor;
        public override Color ForeColor
        {
            get { return _foreColor; }
            set { _foreColor = value; }
        }

        private Color _fouseTextColor;
        public Color FouseTextColor
        {
            get { return _fouseTextColor; }
            set { _fouseTextColor = value; }
        }

        private Color _fouseBorderColor;
        public Color FouseBorderColor
        {
            get { return _fouseBorderColor; }
            set { _fouseBorderColor = value; }
        }

        private Color _backColor;
        public override Color BackColor
        {
            get { return _backColor; }
            set { _backColor = value; }
        }

        private Color _fouseColor;
        public Color FouseColor
        {
            get { return _fouseColor; }
            set { _fouseColor = value; }
        }

        private Color _borderColor;
        public Color BorderColor
        {
            get { return _borderColor; }
            set { _borderColor = value; }
        }

        private IconLayoutType _iconLayoutType;
        [Category("杂项")]
        public IconLayoutType IconLayoutType
        {
            get { return _iconLayoutType; }
            set
            {
                _iconLayoutType = value;
                this.Invalidate();
            }
        }

        private bool _useVisualStyleBackColor;
        [Category("杂项")]
        public bool UseVisualStyleBackColor
        {
            get { return _useVisualStyleBackColor; }
            set { _useVisualStyleBackColor = value; }
        }

        private SizeF _autoScaleDimensions;
        public SizeF AutoScaleDimensions
        {
            get { return _autoScaleDimensions; }
            set { _autoScaleDimensions = value; }
        }

        private AutoScaleMode _autoScaleMode;
        public AutoScaleMode AutoScaleMode
        {
            get { return _autoScaleMode; }
            set { _autoScaleMode = value; }
        }

        //public new bool Enabled
        //{
        //    get { return base.Enabled; }
        //    set
        //    {
        //        base.Enabled = value;
        //        this.Invalidate();
        //    }
        //}

        public NButton()
        {
            InitializeComponent();
            InitializeSettings();
        }

        private void InitializeSettings()
        {
            _foreColor = Color.Black;
            _backColor = SystemColors.Control;
            _fouseColor = Color.White;
            _borderColor = SystemColors.ControlDark;
            _fouseTextColor = Color.Black;
            _fouseBorderColor = Color.Orange;

        }

        private Bitmap Discolor(System.Drawing.Bitmap image)
        {
            //原来图片的长度
            int width = image.Width;
            //原来图片的高度
            int height = image.Height;

            Bitmap _image = new Bitmap(width, height, image.PixelFormat);

            using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(_image))
            {
                g.Clear(_backColor);
                g.DrawImage(image, new Rectangle(0, 0, width, height));
            }           

            //横坐标
            for (int x = 0; x < width; x++)
            {
                //纵坐标
                for (int y = 0; y < height; y++)
                {
                    ////获得坐标(x,y)颜色
                    Color color = _image.GetPixel(x, y);

                    ////获得该颜色下的黑白色
                    int value = (color.R + color.G + color.B) / 3;

                    ////设置颜色
                    _image.SetPixel(x, y, Color.FromArgb(200, value, value, value));
                }
            }

            return _image;

        }

        private GraphicsPath GetRoundedRectPath(Rectangle rect, int radius)
        {
            GraphicsPath roundedRect = new GraphicsPath();
            roundedRect.AddArc(rect.X, rect.Y, radius * 2, radius * 2, 180, 90);
            roundedRect.AddLine(rect.X + radius, rect.Y, rect.Right - radius * 2, rect.Y);
            roundedRect.AddArc(rect.X + rect.Width - radius * 2, rect.Y, radius * 2, radius * 2, 270, 90);
            roundedRect.AddLine(rect.Right, rect.Y + radius * 2, rect.Right, rect.Y + rect.Height - radius * 2);
            roundedRect.AddArc(rect.X + rect.Width - radius * 2, rect.Y + rect.Height - radius * 2, radius * 2, radius * 2, 0, 90);
            roundedRect.AddLine(rect.Right - radius * 2, rect.Bottom, rect.X + radius * 2, rect.Bottom);
            roundedRect.AddArc(rect.X, rect.Bottom - radius * 2, radius * 2, radius * 2, 90, 90);
            roundedRect.AddLine(rect.X, rect.Bottom - radius * 2, rect.X, rect.Y + radius * 2);
            roundedRect.CloseFigure();
            return roundedRect;
        }
        
        protected override void OnPaint(PaintEventArgs e)
        {
            //base.OnPaint(e);

            Graphics graphic = e.Graphics;

            StringFormat sf = new StringFormat();
            sf.LineAlignment = StringAlignment.Center;

            Rectangle clientRection = new Rectangle();
            clientRection.X = 1;
            clientRection.Y = 1;
            clientRection.Width = this.ClientSize.Width - 3;
            clientRection.Height = this.ClientSize.Height - 3;

            Rectangle roundedRection = new Rectangle(clientRection.Location, clientRection.Size);
            System.Drawing.Drawing2D.GraphicsPath roundedPath = null;
            if (_radius > 0)
            {
                roundedPath = GetRoundedRectPath(clientRection, _radius);
                graphic.FillPath(new SolidBrush(BackColor), roundedPath);
            }
            else
            {
                graphic.Clear(BackColor);
            }

            Rectangle textRection = new Rectangle(clientRection.Location, clientRection.Size);

            Rectangle iconRection = new Rectangle(clientRection.X + 2, clientRection.Y + 2, 16, 16);

            sf.Alignment = StringAlignment.Center;

            Pen pen=new Pen(BorderColor);

            if (_foused)
            {
                pen.Color = FouseBorderColor;
                pen.DashStyle = DashStyle.Solid;

                graphic.SmoothingMode = SmoothingMode.HighQuality;

                if (_radius > 0)
                {                  
                    graphic.FillPath(new SolidBrush(FouseColor), roundedPath);
                }
                else
                {
                    graphic.FillRectangle(new SolidBrush(FouseColor), clientRection);
                }

                graphic.SmoothingMode = SmoothingMode.Default; 

            }
            else
            {
                pen.DashStyle = DashStyle.Solid;
            }

            if (_radius > 0)
            {
                textRection.Width = textRection.Width + Radius;
                textRection.Height = textRection.Height + Radius / 2;
            }
            else
            {
                textRection.Height = textRection.Height + 2;
            }

            if (_icon != null && _unableicon != null)
            {
                switch (_iconLayoutType)
                {
                    case IconLayoutType.MiddleLeft:
                        iconRection = new Rectangle(clientRection.X + 4, clientRection.Y + (clientRection.Height - 16) / 2, 16, 16);
                        textRection = new Rectangle(clientRection.X + 4 + 16 + 4, clientRection.Y, clientRection.Width - 24 - 4, textRection.Height);
                        sf.Alignment = StringAlignment.Near;
                        break;
                    case IconLayoutType.MiddleRight:
                        iconRection = new Rectangle(clientRection.X + clientRection.Width - 16 - 4, clientRection.Y + (clientRection.Height - 16) / 2, 16, 16);
                        textRection = new Rectangle(clientRection.X + 4, clientRection.Y, clientRection.Width - 24 - 4, textRection.Height);
                        sf.Alignment = StringAlignment.Near;
                        break;
                    case IconLayoutType.TopCenter:
                        iconRection = new Rectangle(clientRection.X + (clientRection.Width - 16) / 2, clientRection.Y + 4, 16, 16);
                        textRection = new Rectangle(clientRection.X + 4, clientRection.Y + 24, textRection.Width, textRection.Height - 24);
                        break;
                    case IconLayoutType.BottomCenter:
                        iconRection = new Rectangle(clientRection.X + (clientRection.Width - 16) / 2, textRection.Height - 24, 16, 16);
                        textRection = new Rectangle(clientRection.X + 4, clientRection.Y, textRection.Width, textRection.Height - 24);
                        break;
                }

                if (this.Enabled)
                {
                    graphic.DrawImage(this.Icon, iconRection);
                }
                else
                {
                    graphic.DrawImage(this.UnableIcon, iconRection);
                }
            }
           
            if (!string.IsNullOrEmpty(this.Text))
            {
                if (this.Enabled)
                {
                    if (_foused)
                        graphic.DrawString(this.Text, this.Font, new SolidBrush(FouseTextColor), textRection, sf);
                    else
                        graphic.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), textRection, sf);
                }
                else
                {                  
                    graphic.DrawString(this.Text, this.Font, new SolidBrush(SystemColors.ControlDark), textRection, sf);
                }
            }

            graphic.SmoothingMode = SmoothingMode.HighQuality;

            if (!this.Enabled)
            {
                pen.Color = SystemColors.ControlDark;
            }

            if (_radius > 0)
            {
                graphic.DrawPath(pen, roundedPath);
            }
            else
            {
                graphic.DrawRectangle(pen, clientRection);
            }

            graphic.SmoothingMode = SmoothingMode.Default; 
           

        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
            this.Foused = true;
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            this._foused = true;
            this.Invalidate();
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            this._foused = false;
            this.Invalidate();
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            this.Foused = false;
        }

        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (!this.Enabled)
                return false;

            if ((int)keyData == 13)
            {
                PropertyInfo _PropertyInfo = typeof(Control).GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
                if (_PropertyInfo != null)
                {
                    object _EventList = _PropertyInfo.GetValue(this, null);
                    if (_EventList != null && _EventList is EventHandlerList)
                    {
                        EventHandlerList _List = (EventHandlerList)_EventList;                       
                        FieldInfo _FieldInfo = typeof(Control).GetField("EventClick", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
                        if (_FieldInfo != null)
                        {
                            Delegate _ObjectDelegate = _List[_FieldInfo.GetValue(this)];
                            if (_ObjectDelegate == null)
                                return false;
                            _ObjectDelegate.DynamicInvoke(new object[] { this, new EventArgs() });
                        }
                    }
                }
            }
            return base.ProcessDialogKey(keyData);
        }

        protected override void OnClick(EventArgs e)
        {
            if (!this.Enabled)
                return;
            base.OnClick(e);
        }

    }

    public enum IconLayoutType
    {
        MiddleLeft,
        MiddleRight,
        MiddleCenter,
        TopCenter,
        BottomCenter
    }

}
